import 'dart:convert';
import 'dart:math' as math;
import '../models/daily_quiz.dart';
import '../models/word.dart';
import '../../data/master_vocabulary.dart';
import 'storage_service.dart';
import '../../core/constants.dart';
import 'package:shared_preferences/shared_preferences.dart';

class DailyQuizService {
  final StorageService _storageService;
  
  DailyQuizService(this._storageService);

  // 检查VIP状态
  Future<bool> _isVipActive() async {
    final prefs = await SharedPreferences.getInstance();
    final expiryTimestamp = prefs.getInt('vip_expiry_timestamp');
    
    if (expiryTimestamp == null) return false;
    if (expiryTimestamp == -1) return true; // 永久VIP
    
    final expiryDate = DateTime.fromMillisecondsSinceEpoch(expiryTimestamp);
    return expiryDate.isAfter(DateTime.now());
  }

  // 检查今日是否已完成测验（VIP用户可以无限次测试）
  Future<bool> hasTodayQuizCompleted() async {
    // VIP用户可以无限次测试
    final isVip = await _isVipActive();
    if (isVip) return false;
    
    final today = DateTime.now();
    final todayQuizId = 'daily_${today.year}_${today.month}_${today.day}';
    
    final quizzes = await getDailyQuizHistory();
    final todayQuiz = quizzes.firstWhere(
      (quiz) => quiz.id == todayQuizId,
      orElse: () => DailyQuiz.createNew(today, []),
    );
    
    return todayQuiz.isCompleted;
  }

  // 获取今日测验（如果不存在则创建）
  Future<DailyQuiz> getTodayQuiz() async {
    final today = DateTime.now();
    final isVip = await _isVipActive();
    
    // VIP用户每次都生成新的测试
    if (isVip) {
      final questionIds = _generateVipQuestions();
      final vipQuizId = 'vip_${today.year}_${today.month}_${today.day}_${DateTime.now().millisecondsSinceEpoch}';
      return DailyQuiz(
        id: vipQuizId,
        date: today,
        questionIds: questionIds,
        totalQuestions: questionIds.length,
        correctAnswers: 0,
        accuracy: 0.0,
        duration: Duration.zero,
        completedAt: DateTime.now(),
        isCompleted: false,
      );
    }
    
    final todayQuizId = 'daily_${today.year}_${today.month}_${today.day}';
    
    final quizzes = await getDailyQuizHistory();
    final existingQuiz = quizzes.where((quiz) => quiz.id == todayQuizId).isNotEmpty 
        ? quizzes.where((quiz) => quiz.id == todayQuizId).first 
        : null;
    
    if (existingQuiz != null) {
      return existingQuiz;
    }
    
    // 创建新的每日测验
    final questionIds = _generateDailyQuestions(today);
    final newQuiz = DailyQuiz.createNew(today, questionIds);
    
    return newQuiz;
  }

  // 生成每日测验题目（基于日期的伪随机）
  List<String> _generateDailyQuestions(DateTime date) {
    final seed = date.year * 10000 + date.month * 100 + date.day;
    final random = math.Random(seed);
    
    final allWords = MasterVocabulary.allVocabulary;
    final shuffled = List<Word>.from(allWords);
    shuffled.shuffle(random);
    
    // 取前100个单词作为测验题目
    return shuffled.take(100).map((word) => word.id).toList();
  }

  // 为VIP用户生成随机题目（每次都不同）
  List<String> _generateVipQuestions() {
    final random = math.Random();
    
    final allWords = MasterVocabulary.allVocabulary;
    final shuffled = List<Word>.from(allWords);
    shuffled.shuffle(random);
    
    // 取前100个单词作为测验题目
    return shuffled.take(100).map((word) => word.id).toList();
  }

  // 保存测验结果
  Future<void> saveDailyQuizResult(DailyQuiz quiz) async {
    final quizzes = await getDailyQuizHistory();
    final existingIndex = quizzes.indexWhere((q) => q.id == quiz.id);
    
    if (existingIndex != -1) {
      quizzes[existingIndex] = quiz;
    } else {
      quizzes.add(quiz);
    }
    
    // 只保留最近30天的记录
    final thirtyDaysAgo = DateTime.now().subtract(const Duration(days: 30));
    quizzes.removeWhere((quiz) => quiz.date.isBefore(thirtyDaysAgo));
    
    final quizzesJson = quizzes.map((quiz) => jsonEncode(quiz.toJson())).toList();
    await _storageService.prefs.setStringList(AppConstants.KEY_DAILY_QUIZZES, quizzesJson);
  }

  // 获取每日测验历史记录
  Future<List<DailyQuiz>> getDailyQuizHistory() async {
    final quizzesJson = _storageService.prefs.getStringList(AppConstants.KEY_DAILY_QUIZZES) ?? [];
    return quizzesJson.map((json) => DailyQuiz.fromJson(jsonDecode(json))).toList();
  }

  // 获取测验统计信息
  Future<Map<String, dynamic>> getDailyQuizStats() async {
    final quizzes = await getDailyQuizHistory();
    
    if (quizzes.isEmpty) {
      return {
        'totalQuizzes': 0,
        'averageAccuracy': 0.0,
        'bestAccuracy': 0.0,
        'currentStreak': 0,
        'longestStreak': 0,
        'recentQuizzes': <DailyQuiz>[],
      };
    }
    
    final completedQuizzes = quizzes.where((quiz) => quiz.isCompleted).toList();
    final totalQuizzes = completedQuizzes.length;
    
    double averageAccuracy = 0.0;
    double bestAccuracy = 0.0;
    
    if (totalQuizzes > 0) {
      averageAccuracy = completedQuizzes.map((q) => q.accuracy).reduce((a, b) => a + b) / totalQuizzes;
      bestAccuracy = completedQuizzes.map((q) => q.accuracy).reduce((a, b) => a > b ? a : b);
    }
    
    // 计算连续答题天数
    final currentStreak = _calculateCurrentStreak(completedQuizzes);
    final longestStreak = _calculateLongestStreak(completedQuizzes);
    
    // 最近的测验记录（最多10条）
    final recentQuizzes = completedQuizzes
        .toList()
        ..sort((a, b) => b.date.compareTo(a.date));
    
    return {
      'totalQuizzes': totalQuizzes,
      'averageAccuracy': averageAccuracy,
      'bestAccuracy': bestAccuracy,
      'currentStreak': currentStreak,
      'longestStreak': longestStreak,
      'recentQuizzes': recentQuizzes.take(10).toList(),
    };
  }

  // 计算当前连续答题天数
  int _calculateCurrentStreak(List<DailyQuiz> quizzes) {
    if (quizzes.isEmpty) return 0;
    
    final sortedQuizzes = quizzes.toList()
        ..sort((a, b) => b.date.compareTo(a.date));
    
    int streak = 0;
    DateTime currentDate = DateTime.now();
    
    for (final quiz in sortedQuizzes) {
      final quizDate = DateTime(quiz.date.year, quiz.date.month, quiz.date.day);
      final checkDate = DateTime(currentDate.year, currentDate.month, currentDate.day);
      
      if (quizDate.isAtSameMomentAs(checkDate)) {
        streak++;
        currentDate = currentDate.subtract(const Duration(days: 1));
      } else if (quizDate.isBefore(checkDate.subtract(const Duration(days: 1)))) {
        break;
      }
    }
    
    return streak;
  }

  // 计算最长连续答题天数
  int _calculateLongestStreak(List<DailyQuiz> quizzes) {
    if (quizzes.isEmpty) return 0;
    
    final sortedQuizzes = quizzes.toList()
        ..sort((a, b) => a.date.compareTo(b.date));
    
    int longestStreak = 1;
    int currentStreak = 1;
    
    for (int i = 1; i < sortedQuizzes.length; i++) {
      final prevQuiz = sortedQuizzes[i - 1];
      final currentQuiz = sortedQuizzes[i];
      
      final prevDate = DateTime(prevQuiz.date.year, prevQuiz.date.month, prevQuiz.date.day);
      final currentDate = DateTime(currentQuiz.date.year, currentQuiz.date.month, currentQuiz.date.day);
      
      if (currentDate.difference(prevDate).inDays == 1) {
        currentStreak++;
        longestStreak = math.max(longestStreak, currentStreak);
      } else {
        currentStreak = 1;
      }
    }
    
    return longestStreak;
  }
} 